/***************************************************************************
 *   Copyleft 2008-2009 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#include "./vXmlOutputStream.h"

namespace Vendetta {
	vBool vXmlOutputStream::SaveToFile(const vString& fileName) {
		TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "Windows-1252", "");  
		mDocTag.LinkEndChild(decl);
		
		if (!preSave()) {
			return false;
		}

		return mDocTag.SaveFile(fileName.ToConstCharPtr());
	}

	vVoid vXmlOutputStream::setBoolWriteType(vStringConverter::eBoolType boolType) {
		mBoolWriteType = boolType;
	}

	vVoid vXmlOutputStream::openTagForWrite(const vString& tagName) {
		TiXmlElement* elem = new TiXmlElement(tagName.ToConstCharPtr());
		if (mTags.IsEmpty()) {
			mDocTag.LinkEndChild(elem);
		} else {
			TiXmlElement* parent = mTags.Top();
			parent->LinkEndChild(elem);
		}
		mTags<<elem;
	}

	vVoid vXmlOutputStream::closeLastOpenedTagForWrite() {
		if (!mTags.IsEmpty()) {
			mTags.Pop();
		}
	}

	vVoid vXmlOutputStream::closeRemainingTagsForWrite() {
		while (!mTags.IsEmpty()) {
			mTags.Pop();
		}
	}

	vXmlOutputStream& vXmlOutputStream::addAtribute(const vString& attName, const vString& val) {
		try {
			TiXmlElement* elem = mTags.Top();
			elem->SetAttribute(attName.ToConstCharPtr(), val.ToConstCharPtr());
		} catch (vException&) {
			throw vException("There is no tag to attach attribute to. In vXmlOutputStream::addAtribute.");
		}

		return *this;
	}

	vXmlOutputStream& vXmlOutputStream::addAtribute(const vString& attName, vInt val) {
		try {
			TiXmlElement* elem = mTags.Top();
			elem->SetAttribute(attName.ToConstCharPtr(), 
				vStringConverter::ToString(val).ToConstCharPtr());
		} catch (vException&) {
			throw vException("There is no tag to attach attribute to. In vXmlOutputStream::addAtribute.");
		}

		return *this;
	}

	vXmlOutputStream& vXmlOutputStream::addAtribute(const vString& attName, vUInt val) {
		try {
			TiXmlElement* elem = mTags.Top();
			elem->SetAttribute(attName.ToConstCharPtr(), 
				vStringConverter::ToString(val).ToConstCharPtr());
		} catch (vException&) {
			throw vException("There is no tag to attach attribute to. In vXmlOutputStream::addAtribute.");
		}

		return *this;
	}

	vXmlOutputStream& vXmlOutputStream::addAtribute(const vString& attName, vUInt32 val) {
		try {
			TiXmlElement* elem = mTags.Top();
			elem->SetAttribute(attName.ToConstCharPtr(), 
				vStringConverter::ToString(val).ToConstCharPtr());
		} catch (vException&) {
			throw vException("There is no tag to attach attribute to. In vXmlOutputStream::addAtribute.");
		}

		return *this;
	}

	vXmlOutputStream& vXmlOutputStream::addAtribute(const vString& attName, vReal val) {
		try {
			TiXmlElement* elem = mTags.Top();
			elem->SetAttribute(attName.ToConstCharPtr(), 
				vStringConverter::ToString(val).ToConstCharPtr());
		} catch (vException&) {
			throw vException("There is no tag to attach attribute to. In vXmlOutputStream::addAtribute.");
		}

		return *this;
	}

	vXmlOutputStream& vXmlOutputStream::addAtribute(const vString& attName, vChar val) {
		try {
			TiXmlElement* elem = mTags.Top();
			elem->SetAttribute(attName.ToConstCharPtr(), 
				vStringConverter::ToString(val).ToConstCharPtr());
		} catch (vException&) {
			throw vException("There is no tag to attach attribute to. In vXmlOutputStream::addAtribute.");
		}

		return *this;
	}

	vXmlOutputStream& vXmlOutputStream::addAtribute(const vString& attName, vBool val) {
		try {
			TiXmlElement* elem = mTags.Top();
			elem->SetAttribute(attName.ToConstCharPtr(), 
				vStringConverter::ToString(val, mBoolWriteType).ToConstCharPtr());
		} catch (vException&) {
			throw vException("There is no tag to attach attribute to. In vXmlOutputStream::addAtribute.");
		}

		return *this;
	}

	vXmlOutputStream& vXmlOutputStream::addAtribute(const vString& attName, vLong val) {
		try {
			TiXmlElement* elem = mTags.Top();
			elem->SetAttribute(attName.ToConstCharPtr(), 
				vStringConverter::ToString(val).ToConstCharPtr());
		} catch (vException&) {
			throw vException("There is no tag to attach attribute to. In vXmlOutputStream::addAtribute.");
		}

		return *this;
	}

	vXmlOutputStream& vXmlOutputStream::addText(const vString& text) {
		try {
			TiXmlElement* parent = mTags.Top();
			parent->LinkEndChild(new TiXmlText(text.ToConstCharPtr()));
		} catch (vException&) {
			throw vException("There is no tag to attach text to. In vXmlOutputStream::addText.");
		}

		return *this;
	}

	vXmlOutputStream& vXmlOutputStream::addTextTag(const vString& tagName, const vString& text) {
	try {
			TiXmlElement *parent = mTags.Top(), 
				*elem = new TiXmlElement(tagName.ToConstCharPtr());
			elem->LinkEndChild(new TiXmlText(text.ToConstCharPtr()));
			parent->LinkEndChild(elem);
		} catch (vException&) {
			throw vException("There is no tag to attach text to. In vXmlOutputStream::addText.");
		}

		return *this;
	}
}